package org.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @Author：zj@uinpay.cn
 * @Date: 2024/8/24
 * @Desc:
 */
@Configuration
@EnableWebSecurity //开启springSecurity的自定义配置，（spring boot项目可以省略）
@EnableMethodSecurity//基于方法的授权
public class WebSecurityConfig {

    @Bean
    public PasswordEncoder getBCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize ->
                //hasAuthority 输入什么就是什么  hasRole输入的签名拼接role_
                authorize.requestMatchers("/user/list").hasRole("list")//该路径需user_list权限
//                        authorize.requestMatchers("/user/list").hasAuthority("user_list")//该路径需user_list权限
                        // 对所以请求开启权限保护
                        .anyRequest()
                        //已认证的请求不会被自动授权
                        .authenticated());
        //.httpBasic() // 不使用默认
        http.formLogin(fore -> {
            fore.successHandler(new MyAuthenticationSuccHandler())//成功的处理
                    .failureHandler(new MyAuthenticationErrHandler());//失败的处理
        });
        http.formLogin(Customizer.withDefaults());
        http.logout(logout -> {
            logout.logoutSuccessHandler(new MyAuthenticationLogOutHandler()); // 注销的处理
        });

        http.exceptionHandling(ex -> {
            ex.authenticationEntryPoint(new MyAuthenticationEntryPoint());// 请求未认证的处理
            ex.accessDeniedHandler(new MyAccessDeniedHandler());//未授权的处理
        });

        http.sessionManagement(session -> session.maximumSessions(1)// 最大登录账户
                .expiredSessionStrategy(new MySessionInformationExpiredStrategy())); //超时退出的处理

        http.cors(Customizer.withDefaults()); //跨域的处理

        http.csrf(AbstractHttpConfigurer::disable); //关闭防御

        return http.build();
    }


    @Bean
    public UserDetailsService userDetailsService() {
        // @Component 通过注解创建
        DbUserDetailsManage dbUserDetailsManage = new DbUserDetailsManage();
        return dbUserDetailsManage;
    }
}
